<script setup lang="ts">
import { computed, ref } from 'vue';

import {
  ElButton,
  ElDescriptions,
  ElDialog,
  ElOption,
  ElRadio,
  ElRadioGroup,
} from 'element-plus';
import * as monaco from 'monaco-editor';

import { useEditorStore } from '@/store';

defineOptions({
  name: 'MonacoEditorSetting',
});

const { fontSize, theme } = defineProps({
  fontSize: {
    default: () => 16,
    type: Number,
  },
  theme: {
    default: () => 'vs',
    type: String,
  },
});
const fontSizeOptions = Array.from({ length: 11 }, (_, i) => ({
  label: `${i + 10}px`,
  value: i + 10,
}));

const themeOptions = [
  { label: '浅色（默认）', value: 'vs' },
  { label: '深色', value: 'vs-dark' },
  { label: '深色高对比度', value: 'hc-black' },
];
const editorStore = useEditorStore();
const visible = ref(false);
const options = ref({
  automaticLayout: true,
  contextmenu: true,
  cursorStyle: 'line',
  folding: true,
  foldingHighlight: true,
  fontSize,
  guides: {
    indentation: true,
  },
  lineNumbers: 'on',
  minimap: {
    enabled: true,
    scale: 1,
  },
  renderLineHighlight: 'none',
  scrollbar: {
    alwaysConsumeMouseWheel: false,
    arrowSize: 10,
    horizontalScrollbarSize: 5,
    verticalScrollbarSize: 5,
  },
  theme,
});
const defaultOptions = computed(() => {
  return editorStore.options;
});

const open = () => {
  Object.assign(options.value, defaultOptions.value);
  visible.value = true;
};

const onConfirm = () => {
  const data =
    options.value as monaco.editor.IStandaloneEditorConstructionOptions;
  editorStore.updateOptions(data);
  visible.value = false;
};
defineExpose({
  open,
});
</script>

<template>
  <ElDialog
    v-model="visible"
    :align-center="true"
    :center="true"
    :draggable="true"
    :show-close="false"
    modal-class="editor-more-setting-dialog"
    width="640"
  >
    <template #header>
      <div class="dialog-header">更多设置</div>
    </template>
    <div class="dialog-body">
      <ElDescriptions :column="1" border size="small" title="常用设置">
        <ElDescriptionsItem
          label="主题"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.theme">
            <ElRadio
              v-for="item in themeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
              size="small"
            />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="控制字体大小(像素)"
          label-align="right"
          label-class-name="label-style"
        >
          <ElSelect
            v-model="options.fontSize"
            :fit-input-width="true"
            size="small"
          >
            <ElOption
              v-for="item in fontSizeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
              <ElText :style="{ 'font-size': `${item.value}px` }">
                {{ item.label }}
              </ElText>
            </ElOption>
          </ElSelect>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="是否行号"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.lineNumbers">
            <ElRadio label="是" size="small" value="on" />
            <ElRadio label="否" size="small" value="off" />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="控制光标样式"
          label-align="right"
          label-class-name="label-style"
        >
          <ElSelect
            v-model="options.cursorStyle"
            popper-class="editor-more-setting-select"
            size="small"
          >
            <ElOption label="line" value="line">
              <ElText class="option-left">line</ElText>
              <ElText class="option-right"> 默认 </ElText>
            </ElOption>
            <ElOption label="block" value="block" />
            <ElOption label="underline" value="underline" />
            <ElOption label="line-thin" value="line-thin" />
            <ElOption label="block-outline" value="block-outline" />
            <ElOption label="underline-thin" value="underline-thin" />
          </ElSelect>
        </ElDescriptionsItem>
      </ElDescriptions>
      <ElDescriptions :column="1" border size="small" title="文本编辑器">
        <ElDescriptionsItem
          label="是否启用代码折叠"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.folding">
            <ElRadio :value="true" label="是" size="small" />
            <ElRadio :value="false" label="否" size="small" />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="是否应突出显示折叠范围"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.foldingHighlight">
            <ElRadio :value="true" label="是" size="small" />
            <ElRadio :value="false" label="否" size="small" />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="是否显示缩进参考线"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.guides.indentation">
            <ElRadio :value="true" label="是" size="small" />
            <ElRadio :value="false" label="否" size="small" />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="当前行进行高亮显示的方式"
          label-align="right"
          label-class-name="label-style"
        >
          <ElSelect
            v-model="options.renderLineHighlight"
            popper-class="editor-more-setting-select"
            size="small"
          >
            <ElOption label="none" value="none" />
            <ElOption label="gutter" value="gutter" />
            <ElOption label="line" value="line">
              <ElText class="option-left">line</ElText>
              <ElText class="option-right"> 默认 </ElText>
            </ElOption>
            <ElOption label="all" value="all" />
          </ElSelect>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="是否显示缩略图"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.minimap.enabled">
            <ElRadio :value="true" label="是" size="small" />
            <ElRadio :value="false" label="否" size="small" />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="缩略图显示比例"
          label-align="right"
          label-class-name="label-style"
        >
          <ElSelect
            v-model="options.minimap.scale"
            popper-class="editor-more-setting-select"
            size="small"
          >
            <ElOption :value="1" label="1">
              <ElText class="option-left">1</ElText>
              <ElText class="option-right"> 默认 </ElText>
            </ElOption>
            <ElOption :value="2" label="2" />
            <ElOption :value="3" label="3" />
          </ElSelect>
        </ElDescriptionsItem>
      </ElDescriptions>
      <ElDescriptions :column="1" border size="small" title="窗口设置">
        <ElDescriptionsItem
          label="自动适应布局"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.automaticLayout">
            <ElRadio :value="true" label="是" size="small" />
            <ElRadio :value="false" label="否" size="small" />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="是否使用右键菜单上下文菜单"
          label-align="right"
          label-class-name="label-style"
        >
          <ElRadioGroup v-model="options.contextmenu">
            <ElRadio :value="true" label="是" size="small" />
            <ElRadio :value="false" label="否" size="small" />
          </ElRadioGroup>
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="水平滚动条宽度"
          label-align="right"
          label-class-name="label-style"
        >
          <ElInputNumber
            v-model="options.scrollbar.horizontalScrollbarSize"
            :controls="false"
            :max="20"
            :min="5"
            size="small"
          />
        </ElDescriptionsItem>
        <ElDescriptionsItem
          label="垂直滚动条宽度"
          label-align="right"
          label-class-name="label-style"
        >
          <ElInputNumber
            v-model="options.scrollbar.verticalScrollbarSize"
            :controls="false"
            :max="20"
            :min="5"
            size="small"
          />
        </ElDescriptionsItem>
      </ElDescriptions>
    </div>
    <template #footer>
      <div class="flex items-center justify-end dialog-footer">
        <ElButton size="small" @click="visible = false">关闭</ElButton>
        <ElButton size="small" type="primary" @click="onConfirm">
          确定
        </ElButton>
      </div>
    </template>
  </ElDialog>
</template>
<style lang="scss">
.editor-more-setting-dialog {
  .dialog-header {
    font-size: 14px;
    color: var(--el-text-color-primary);
  }

  .dialog-body {
    display: flex;
    flex-direction: column;
    gap: 16px;
    height: 640px;
    overflow: auto;

    .label-style {
      width: 180px !important;
    }

    .el-select__wrapper {
      box-shadow: none !important;
    }

    .el-input-number.is-without-controls .el-input__wrapper {
      padding: 2px 8px !important;
      box-shadow: none !important;

      .el-input__inner {
        text-align: left !important;
      }
    }
  }
}

.editor-more-setting-select {
  .el-select-dropdown__item {
    .option-left {
      float: left;
    }

    .option-right {
      float: right;
      font-size: 12px;
      color: var(--el-text-color-secondary);
    }
  }
}
</style>
